package com.upstairstechnology.oi;

import java.io.IOException;
import java.util.Set;

import javax.mail.MessagingException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;

import com.upstairstechnology.oi.determination.DeterminationStrategy;
import com.upstairstechnology.oi.determination.IntegrationCheck;
import com.upstairstechnology.oi.determination.OutstandingIntegration;
import com.upstairstechnology.oi.notification.NotificationHandler;

/**
 * Run the outstanding integrations checker.
 * 
 * @author Jeff Jensen
 */
public class OiRunner {
    /** Logger instance. */
    private static final Logger LOGGER =
            LoggerFactory.getLogger(OiRunner.class);

    /** Strategy to determine the outstanding integrations. */
    private DeterminationStrategy determinationStrategy;

    /** Handler to process notifications. */
    private NotificationHandler notificationHandler;

    /** Set of integration checks to do. */
    private Set<IntegrationCheck> integrationChecks;

    /**
     * Run the program.
     * 
     * @throws IOException
     *             When errors occur while processing the SCM system output or
     *             processing email notifications.
     * @throws MessagingException
     *             When errors occur sending emails.
     */
    public void run() throws IOException, MessagingException {
        LOGGER.debug("determinationStrategy={}", determinationStrategy);
        LOGGER.debug("notificationHandler={}", notificationHandler);
        LOGGER.debug("integrationChecks={}", integrationChecks);

        Set<OutstandingIntegration> oiSet =
                determinationStrategy
                        .determineOutstandingIntegrations(integrationChecks);
        LOGGER.info("Determined outstanding integrations set={}", oiSet);

        notificationHandler.handle(oiSet);
    }

    /**
     * Get the determination strategy.
     * 
     * @return The determination strategy.
     */
    public DeterminationStrategy getDeterminationStrategy() {
        return determinationStrategy;
    }

    /**
     * Get the set of integration checks.
     * 
     * @return The set of integration checks.
     */
    public Set<IntegrationCheck> getIntegrationChecks() {
        return integrationChecks;
    }

    /**
     * Set the determination strategy.
     * 
     * @param strategy
     *            The strategy.
     */
    @Required
    public void setDeterminationStrategy(DeterminationStrategy strategy) {
        this.determinationStrategy = strategy;
    }

    /**
     * Set the integration check set.
     * 
     * @param set
     *            The set to check.
     */
    @Required
    public void setIntegrationChecks(Set<IntegrationCheck> set) {
        this.integrationChecks = set;
    }

    /**
     * Get the notification handler.
     * 
     * @return The notification handler.
     */
    public NotificationHandler getNotificationHandler() {
        return notificationHandler;
    }

    /**
     * Set the notification handler.
     * 
     * @param handler
     *            The notification handler.
     */
    public void setNotificationHandler(NotificationHandler handler) {
        this.notificationHandler = handler;
    }
}
